package com.vsoft.sms_cm;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.Logger;

import com.vsoft.framework.core.BaseException;
import com.vsoft.framework.core.BusiObj;
import com.vsoft.framework.core.db.DBTrans;
import com.vsoft.framework.core.db.OperAgent;
import com.vsoft.framework.core.db.SQLArgs;
import com.vsoft.framework.core.util.BOHelper;
import com.vsoft.framework.core.util.LogCollect;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import com.vsoft.framework.core.Configuration;

public class BatchActivation {
	private static Logger vLogger 		=	Logger.getLogger(BatchActivation.class);
	private static String vName 		=	BatchActivation.class.getName();

    private final static String	RESULT	="RESULT";
	private String vDebugHome 			=	"";
	private int	COMMITRECORDS			=	100;
	//add at 20120408 
	private static boolean	flagDebug	=	false;
	HashMap<String,HashMap<String,String> >	hSetTableConfig		=	new	HashMap<String,HashMap<String,String> >();
	HashMap<String,String> hWpTemple	=	new HashMap<String,String>();
	//add at 20121210 增加个人短信模板支持；
	HashMap<String,String> hWpTemple_person	=	new HashMap<String,String>();
	HashMap<String,ArrayList<String>>	hTablesPK							=	new	HashMap<String,ArrayList<String>>();
	HashMap<String,HashMap<String,String>>	hTablesColumnsInfo	=	new	HashMap<String,HashMap<String,String>>();
	Connection vconn					=	null;
	PreparedStatement pst 				=	null;
	ResultSet rs 						=	null;
	private	String	CUSTOMER_GROUP		=	"CUSTOMER_GROUP";
	private String	ENTERPRISE			=	"ENTERPRISE";
	private	String	ORDER_INFO			=	"ORDER_INFO";
	private String	PRICE_PLAN_INST		=	"PRICE_PLAN_INST";
	private	String	SMS_TEMPLETE		=	"SMS_TEMPLETE";
	private	String	TRIGGER_PHONE		=	"TRIGGER_PHONE";
	private	String	SMS_TEMPLE_GROUP	=	"SMS_TEMPLE_GROUP";
	private	String	SMS_TEMPLE_RULES_REAL	
										=	"SMS_TEMPLE_RULES_REAL";
	private	String	LOG_BATCH_BIZSF		=	"LOG_BATCH_BIZSF";
	private	String	TABLE_NAME			=	"TABLE_NAME";
	private	String	LIST_NAME			=	"LIST_NAME";
	private	boolean	bDebugFlag			=	false;
	private	String	exp_date_2090		=	"",
							eff_date_now		=	"";
	private	boolean	bWpBatchFlag		=	false;
	private	String	PROVINCE_AREA_CODE	=	"0";
	private	String	varEntName			=	"$ENT_NAME$",
					varOrderNum			=	"$ORDER_NUM$";
	private	HashMap<String,PreparedStatement>	hPst	=	new HashMap<String,PreparedStatement>();
	private	HashMap<String,ArrayList<String>>	hPstTablesCols	=	new HashMap<String,ArrayList<String>>();
	boolean	bDebugRowsLimit=false;
	//private BusiObj				vInBO			= null;
	private CmPublic 		 __CmPublic;
	BatchActivation(Connection conn,boolean debug)throws BaseException
	{
		vconn							=	conn;
		__CmPublic 						= 	new CmPublic(conn);
		if(debug)
			this.setDebugFlag();
		initSetTableConfig();
		initTableMetaData(conn);	//add at 20121110
		initPrepareStatement(conn);//add at 20121110
		initWpTempleInfo(conn);		//add at 20121107 
		initWpTempleInfo4Person(conn);		//add at 20121210 
		genFixEffExp();
	}
	public  void setDebugFlag() throws BaseException
	{
		bDebugFlag						=	true;
	}
	public  void setDebugRowsLimit() throws BaseException
	{
		bDebugRowsLimit					=	true;
	}
	public  void setCOMMITRECORDS(int	records) throws BaseException
	{
		if(records<1 || records>1000)
			records	=	10;
		COMMITRECORDS					=	records;
	}
	//初始化模版
	private void initWpTempleInfo(Connection conn)throws BaseException
	{
		String	sql	=	"select  t1.wp_temple_id,t1.wp_temple_context from wp_temple_info t1 ";
		SQLArgs 	Arg					= 	new SQLArgs();
		
		BusiObj		wpTempleInfoBo 	
										= OperAgent.execQuery(conn, "initWpTempleInfo", sql, Arg,true);
		ArrayList<BusiObj> alWPTempleInfo			
										=	wpTempleInfoBo.getBusiObjList(RESULT);

		for(BusiObj n:alWPTempleInfo)
		{
			hWpTemple.put(n.getString("wp_temple_id"),n.getString("wp_temple_context"));
		}
	}
	///////////////////////////////////////////////
	//add at 20121210
	//初始化模版（个人）
	private void initWpTempleInfo4Person(Connection conn)throws BaseException
	{
		String	sql	=	"select  t1.wp_temple_id,t1.wp_temple_context from wp_temple_info_person t1 ";
		SQLArgs 	Arg					= 	new SQLArgs();
		
		BusiObj		wpTempleInfoBo 	
										= OperAgent.execQuery(conn, "initWpTempleInfo4Person", sql, Arg,true);
		ArrayList<BusiObj> alWPTempleInfo			
										=	wpTempleInfoBo.getBusiObjList(RESULT);

		for(BusiObj n:alWPTempleInfo)
		{
			hWpTemple_person.put(n.getString("wp_temple_id"),n.getString("wp_temple_context"));
		}
	}
	///////////////////////////////////////////////
	//初始化元数据，装载到指定的内存中。
	private void initTableMetaData(Connection conn)throws BaseException
	{
		if(hSetTableConfig==null)
			throw new BaseException("batchActivation-0010","没有初始化数据表名数据。。");
		for(String tableName:hSetTableConfig.keySet())
		{
			ArrayList<String>	aTableKey	=	this.getTableKey(tableName,conn);//得到主键
			if(aTableKey.size()<1)
				throw new BaseException(vName +"-007","表名为："+tableName+"没有定义主键，不能使用方法setTableData进行数据处理！");
			hTablesPK.put(tableName, aTableKey);
			
			HashMap<String,String>	hTableColumnsInfo	=	new	HashMap<String,String>();
			hTableColumnsInfo			=	this.getTableColumnsInfo(tableName, conn);
			hTablesColumnsInfo.put(tableName, hTableColumnsInfo);
		}
	}
	/**获取一个表的主键字段
	 * 入参：
	 * tableName：表名
	 * conn：数据库连接
	 * 出参：
	 * 返回 ArrayList<String>
	 * */
	private ArrayList<String> getTableKey(String tableName,Connection conn) throws BaseException
	 {
		   ArrayList<String>	aTableKey	=	new	ArrayList<String>();
		   ResultSet	rs				=	null;
		   DatabaseMetaData dbmd		=	null;
		   String 	columnName;
		   int		key_col				=	0;
		   try
		   {
			   dbmd						=  conn.getMetaData();   
			   rs 						= dbmd.getPrimaryKeys(null,dbmd.getUserName(),tableName.toUpperCase());    //要将表名转为大写才能正确取出主键来
			   while   (rs.next()) 
			   {
				   key_col++;
				   columnName			=	rs.getString(4);
				   aTableKey.add(columnName);
			   }
			}
			catch(SQLException e)
			{
				throw new BaseException(vName +"-006","获取表名为："+tableName+"的主键出错！");
			}
			finally
			{
		    	try
		    	{		    		
		    		rs.close();
		    		dbmd				=	null;
		    	}
		    	catch(Exception e){}
			}   

			return		aTableKey;
	 }
	/**获取一个表的字段信息（元数据）
	 * 入参：
	 * tableName：表名
	 * conn：数据库连接
	 * 出参：
	 * 返回 ArrayList<String>
	 * */
	private HashMap<String,String> getTableColumnsInfo(String tableName,Connection conn) throws BaseException
	 {
		   
		   ResultSet	rs				=	null;
		   DatabaseMetaData dbmd		=	null;
		   String	columnName			=	"",columnDataType="";
		   HashMap<String,String> hColInfo	=	new HashMap<String,String>();
		   int		key_col				=	0;
		   try
		   {
			   dbmd						=  conn.getMetaData();   
			    //要将表名转为大写才能正确取出主键来
			   HashMap<String,String> hColName	=	new HashMap<String,String>();
			   
			   rs						=	dbmd.getColumns(null, dbmd.getUserName(), tableName.toUpperCase(), null);
			   while   (rs.next()) 
			   {
				   key_col++;
				   columnName			=	rs.getString(4).trim();
				   String cName			=	hColName.get(columnName);
				   /////////////////////20120322突然取dbmd.getColumns得到重复列。。。。
				   if(__CmPublic.isStrNullOrEmpty(cName))
					   hColName.put(columnName, "1");
				   else
					   continue;
				   /////////////////////
				   columnDataType		=	rs.getString(6);
				   
				   hColInfo.put(columnName, columnDataType);
				   
			   }
			}
			catch(SQLException e)
			{
				throw new BaseException(vName +"-007","获取表名为："+tableName+"的列信息出错！");
			}
			finally
			{
		    	try
		    	{		    		
		    		rs.close();
		    		dbmd				=	null;
		    	}
		    	catch(Exception e){}
			}   

			return		hColInfo;
	 }
	//生成调试模式的表名:调试模式则在表名后面增加_dbg
	private String genTableName4DebugMode(String tableName)
	{
	   String	ret						=	"";
	   if(tableName.toUpperCase().endsWith(LOG_BATCH_BIZSF))
		   return tableName;
	   if(bDebugFlag)
		   ret							=	(tableName+"_dbg").toUpperCase();
	   else
		   ret							=	tableName.toUpperCase();
	   
	   return	ret;
		   
	}
	//初始化statement，即生成每个表的insert语句（根据元数据），形成批量更新sql，
	//并形成statement的队列，等候使用，并且还加入了每个表的列信息，以备在更新前打入变量值做准备。
	private	void initPrepareStatement(Connection conn)throws BaseException
	{
		String 	tableCols				=	" ",tableColsVar="";
		String	columnDataType			=	"";
		String 	sql						=	" ";
		try
		   {
			   for(String tableName:hSetTableConfig.keySet())
			   {
			   
				   String colValue				=	"";

				   tableName			=	this.genTableName4DebugMode(tableName);
				   String	pkTable		=	this.getPKTableName(tableName);
				   HashMap<String, String>	hTableColsInfo	=	hTablesColumnsInfo.get(pkTable);
				   ArrayList<String >	aColName	=	new ArrayList<String >();
				   for(String colName:hTableColsInfo.keySet())
				   {
					   tableCols		=	tableCols+colName+", ";
					   
					   columnDataType	=	hTableColsInfo.get(colName);
					   if(columnDataType.equals("DATE") //&& !CmPublic.isStrNullOrEmpty(colValue) 
							   )
						   tableColsVar	=	tableColsVar+"TO_DATE("+"?,'YYYY-MM-DD HH24:MI:SS')"+", ";
					   else
						   tableColsVar	=	tableColsVar+"?, ";
					   aColName.add(colName);
				   }
			
				   tableCols			=	this.processCols(tableCols);
				   tableColsVar			=	this.processCols(tableColsVar);
				   sql					=	" Insert Into  "+tableName+" ( "+tableCols+") Values ("+tableColsVar+") ";
				   PreparedStatement pstmt		=	conn.prepareStatement(sql); 
				   hPst.put(tableName, pstmt);
				   hPstTablesCols.put(tableName, aColName);
				   tableCols			=	"";
				   tableColsVar			=	"";
			   }

		   }
		catch(SQLException e)
			{
				throw new BaseException(vName +"-029","生成批量更新sql出错：\n sql="+sql+"\n"+e.getMessage());
			}
		finally
			{
		    	try
		    	{		    		
		    		//rs.close();

		    	}
		    	catch(Exception e){}
			}   
	}
	//初始化表信息
	private void initSetTableConfig()
	{
		HashMap<String,String>	hTable	=	new	HashMap<String,String>();
		//1	ENTERPRISE
		hTable.put(TABLE_NAME, ENTERPRISE);
		hTable.put(LIST_NAME, "ENTERPRISELIST");
		hSetTableConfig.put(ENTERPRISE, hTable);
		//2 ORDER_INFO
		hTable							=	new	HashMap<String,String>();
		hTable.put(TABLE_NAME, ORDER_INFO);
		hTable.put(LIST_NAME, "orderList");
		hSetTableConfig.put(ORDER_INFO, hTable);
		//3 PRICE_PLAN_INST
		hTable							=	new	HashMap<String,String>();
		hTable.put(TABLE_NAME, PRICE_PLAN_INST);
		hTable.put(LIST_NAME, "pricePlanInstList");
		hSetTableConfig.put(PRICE_PLAN_INST, hTable);
		//4 CUSTOMER_GROUP
		hTable							=	new	HashMap<String,String>();
		hTable.put(TABLE_NAME, CUSTOMER_GROUP);
		hTable.put(LIST_NAME, "customerGroupList");
		hSetTableConfig.put(CUSTOMER_GROUP, hTable);
		//5 SMS_TEMPLETE
		hTable							=	new	HashMap<String,String>();
		hTable.put(TABLE_NAME, SMS_TEMPLETE);
		hTable.put(LIST_NAME, "smsTempleList");
		hSetTableConfig.put(SMS_TEMPLETE, hTable);
		//6 TRIGGER_PHONE
		hTable							=	new	HashMap<String,String>();
		hTable.put(TABLE_NAME, TRIGGER_PHONE);
		hTable.put(LIST_NAME, "triggerPhoneList");
		hSetTableConfig.put(TRIGGER_PHONE, hTable);
		//7 SMS_TEMPLE_GROUP
		hTable							=	new	HashMap<String,String>();
		hTable.put(TABLE_NAME, SMS_TEMPLE_GROUP);
		hTable.put(LIST_NAME, "smsTempleGroupList");
		hSetTableConfig.put(SMS_TEMPLE_GROUP, hTable);
		//8 sms_temple_rules_real
		hTable							=	new	HashMap<String,String>();
		hTable.put(TABLE_NAME, SMS_TEMPLE_RULES_REAL);
		hTable.put(LIST_NAME, "smsTempleRulesRealList");
		hSetTableConfig.put(SMS_TEMPLE_RULES_REAL, hTable);
		
		//9 sms_temple_rules_real
		hTable							=	new	HashMap<String,String>();
		hTable.put(TABLE_NAME, LOG_BATCH_BIZSF);
		hTable.put(LIST_NAME, "log_batch_bizsfList");
		hSetTableConfig.put(LOG_BATCH_BIZSF, hTable);
	}

	//获取各地市的旺铺用户数
	private String queryCount4AllValidWPInfo(String condition)
	{
			String sql 					=	" select count(1) cnt,tt1.area_code area_code " +
											" from order_info tt1 ,enterprise tt3 " +
											" where 1=1  " +
											condition	+
											" and wp_state=1 " +
											" and tt1.ent_code=tt3.ent_code " +
											" and tt3.state=1 " +
											" group by tt1.area_code order by tt1.area_code" ;
			return sql;
	}
	//获取各地市未激活的旺铺用户数
	private String queryCount4NotActivationWPInfo(String condition)
	{
			String sql 					=	" select count(1) cnt,tt1.area_code area_code " +
											" from order_info tt1 ,enterprise tt3 " +
											" where wp_state=1 " +
											condition	+
											" and not exists (select 1 from sms_templete tt2 where tt1.ent_code=tt2.ent_code and (tt2.state=1 or (tt2.state=0 and tt2.operator='9999'))) " +
											" and tt1.ent_code=tt3.ent_code " +
											" and tt3.state=1 " +
											" group by tt1.area_code " +
											" order by tt1.area_code " ;//
			return sql;
	}
	//获取各地市未激活的旺铺用户数
	private String queryNotActivationWPInfo(String condition)
	{
			String sql 					=	" select tt1.vouch_number vouch_number,tt1.ent_code ent_code, " +
											" tt1.wp_order_time wp_order_time,tt1.wp_biz_type wp_biz_type," +
											" tt1.wp_state wp_state,tt1.wp_oper_time wp_oper_time," +
											" tt1.wp_eff_date wp_eff_date, tt1.order_sn order_sn," +
											" tt1.area_code area_code,tt1.offer_id offer_id," +
											" tt3.ent_name cust_name" +
											" from order_info tt1 ,enterprise tt3 " +
											" where wp_state=1 " +
											condition	+
											" and not exists (select 1 from sms_templete tt2 where tt1.ent_code=tt2.ent_code and (tt2.state=1 or (tt2.state=0 and tt2.operator='9999'))) " +
											" and tt1.ent_code=tt3.ent_code " +
											" and tt3.state=1 " ;//
			if(bDebugFlag&&bDebugRowsLimit)
				sql						=	sql	+	" and rownum<10";
			return sql;
	}
	//获取期间的激活占比 
	private String genPeriodPercent(String condition)
	{
			String sql 					=	" select t.period period,t.percent percent,t.start_flag start_flag " +
											" from PERIOD_PER t " +
											" where 1=1 " +
											condition +
											" order by t.period" ;
			return sql;
	}
	private int genRandom()
	{
		return genRandom(500);
	}
	//随机数，用于设置不同地市的占比
	private int genRandom(long seed)
	{
		int random						=	0;
		double r2 						=	Math.random(); 
		random=(int) (r2*seed);
		//vLogger.info("=========random :" +random+";   seed="+seed+";   r2="+r2);
/*		Random random1 = new Random();
		random	=	random1.nextInt();*/
		return random;
	}
	//手动执行激活某一个月的用户生成模版
	public void doActivationManual(Connection conn,String period)throws BaseException
	{
		
		String sqlCond					=	" and period ="+period;
		String sql 						=	genPeriodPercent(sqlCond);
		SQLArgs 	Arg					= 	new SQLArgs();
		BusiObj		periodPercentBo 	=	OperAgent.execQuery(conn, "genPeriodPercent", sql, Arg,true);
		ArrayList<BusiObj> alPeriodPercent			
										=	periodPercentBo.getBusiObjList(RESULT);
		if(alPeriodPercent.size()<1)
			throw new BaseException("batchActivation-0001","没有该期间数据："+period);
		else
			doBatch(conn,alPeriodPercent.get(0));

	}
	public void doActivationAuto(Connection conn)throws BaseException
	{
		String sqlCond					=	"";
		String sql 						=	genPeriodPercent(sqlCond);
		SQLArgs 	Arg					= 	new SQLArgs();
		Arg.reset();
		//vLogger.info("doActivation (1)query genPeriodPercent  sql:" +sql);
		BusiObj		periodPercentBo 	= OperAgent.execQuery(conn, "genPeriodPercent", sql, Arg,true);
		ArrayList<BusiObj> alPeriodPercent			
										=	periodPercentBo.getBusiObjList(RESULT);
		boolean bDoBatch				=	false;
		for(BusiObj m:alPeriodPercent)
		{
			String	period				=	m.getString("period");
			String	percent				=	m.getString("percent");
			if(CmPublic.isStrNullOrEmpty(percent))
				continue;
			String	start_flag			=	m.getString("start_flag");
			if(CmPublic.isStrNullOrEmpty(start_flag))
				start_flag				=	"0";
			if(start_flag.trim().equals("1"))
				bDoBatch				=	true;
			if(bDoBatch)
			{
				
				doBatch(conn,m);
			}
		}
	}
	private int genLimit(int iPercent,int cnt)
	{
		double percent 					= iPercent;
		double count					=	cnt;
		double limit					=	count*(percent/10000);
		
		int iLimit						=	(int) limit;
		//vLogger.info("\n=========iLimit="+iLimit+";    limit :" +limit+";   percent="+percent+";   count="+count);
		return iLimit;
	}
	private	void setWpBatchFlag()
	{
		bWpBatchFlag					=	true;
	}
	private void  doBatch(Connection conn,BusiObj periodPercentBo) throws BaseException
	{
		//准备
		//1.1	设置旺铺批量处理标志，主要牵涉模板的状态和很多时间的处理
		setWpBatchFlag();
		//1.2	获取批量处理的期间和总体比例
		String	period					=	periodPercentBo.getString("period");
		String	percent					=	periodPercentBo.getString("percent");
		int iPercent					=	Integer.parseInt(percent);
		vLogger.info("period="+period+"===========doBatch start=============overall percent="+percent);

		//2、设置限额配置数据
		HashMap<String ,BusiObj>hConfig	=	setupConfig(conn, periodPercentBo);

		//3、主要业务进程，激活旺铺用户
		//3.1初始化order
		BusiObj		StaticBO			=	new BusiObj() ;
		StaticBO.setConnection(conn);
		StaticBO.setString(TABLE_NAME, "order_info.OFFER_SMS_CNT");
		Order order						=	 new Order();
		order.init(StaticBO);
		//3.2获取默认的rulesid
		BusiObj	genRulesIBo				=	new BusiObj();
		genRulesIBo.setConnection(conn);
		String rules_ins_id 			=	genRulesInsId(genRulesIBo, order);
		//3.3读取未激活旺铺用户数据，准备生成模版
		String sqlCond					=	genPeriodCondition(period);
		String	sql						=	queryNotActivationWPInfo(sqlCond);
		SQLArgs 	Arg					= 	new SQLArgs();
		//vLogger.info("doBatch(2)query genCount4NotActivationWPInfo  sql:" +sql);
		BusiObj		notActivationWPInfoBo 	
										= OperAgent.execQuery(conn, "genNotActivationWPInfo", sql, Arg,true);
		ArrayList<BusiObj> alNotActivationWPInfo			
										=	notActivationWPInfoBo.getBusiObjList(RESULT);

		boolean bContinue4Province		=	false,
				bContinue4Area			=	false;
		int	cycleCnt					=	0;
		String	exp_date				=	CmPublic.genEffExpDate(2);
		for(BusiObj n:alNotActivationWPInfo)
		{
			String area_code			=	n.getString("area_code");
			String vouch_number			=	n.getString("vouch_number");
			String ent_code				=	n.getString("ent_code");
			String wp_order_time		=	n.getString("wp_order_time");
			String wp_biz_type			=	n.getString("wp_biz_type");
			String wp_state				=	n.getString("wp_state");
			String wp_oper_time			=	n.getString("wp_oper_time");
			String wp_eff_date			=	n.getString("wp_eff_date");
			String order_sn				=	n.getString("order_sn");
			String cust_name			=	n.getString("cust_name");
			String offer_id				=	n.getString("offer_id");
			String original_offer_id	=	offer_id;
			if(__CmPublic.isStrNullOrEmpty(offer_id))
				offer_id				=	"2000";
			BusiObj	bo					=	new BusiObj();
			bo.setConnection(conn);
			bo.setString("area_code", area_code);
			String	area_no				=	genAreaNoByAreaCode(bo, order);
			
			bo.setString("area_no", area_no);
			bo.setString("vouch_number", vouch_number);
			bo.setString("ent_code", ent_code);
			bo.setString("wp_order_time", wp_order_time);
			bo.setString("wp_biz_type", wp_biz_type);
			bo.setString("wp_state", wp_state);
			bo.setString("wp_oper_time", wp_oper_time);
			bo.setString("wp_eff_date", wp_eff_date);
			bo.setString("order_sn", order_sn);
			bo.setString("cust_name", cust_name);
			bo.setString("order_num", vouch_number);
			bo.setString("wp_batch_flag", "1");
			bo.setString("offer_id", offer_id);
			bo.setString("group_type", "0");
			bo.setString("rules_ins_id", rules_ins_id);
			
			bo.setString("original_offer_id", original_offer_id);
			bo.setString("exp_date", exp_date);
			bo.setString("oper_time", CmPublic.getSysdate());//add at 20121106
			bo.setString("period", period);//add at 20121107,为生成每个模版的时间，这里只有年月
			//判断总体比例/限额与地区限额
			//省激活比例达标，则不再进行激活
			BusiObj	configProviceBo		=	hConfig.get(PROVINCE_AREA_CODE);
			bContinue4Province			=	canDoBatch4AreaLimit(configProviceBo);
			if(!bContinue4Province)
				break;
			//地市激活比例达标，该记录则不再进行激活，进行下一次循环
			BusiObj	configAreaBo		=	hConfig.get(area_code);
			bContinue4Area				=	canDoBatch4AreaLimit(configAreaBo);
			if(!bContinue4Area)
				continue;
			//更新总体限额与地区限额
			configProviceBo				=	updateAreaConfig(configProviceBo);
			hConfig.put(PROVINCE_AREA_CODE, configProviceBo);
			configAreaBo				=	updateAreaConfig(configAreaBo);
			hConfig.put(area_code, configAreaBo);
			
			//生成业务数据
			cycleCnt++;
			this.genWPInfo(bo, order);
			
			//日志 20121104
			logBatchBiz(bo);
			//10条已提交
			if(cycleCnt%COMMITRECORDS==0)
			{
				dbExcuteBatch(conn);
				dbCommit(conn);
			}
		}
		dbExcuteBatch(conn);
		dbCommit(conn);
		vLogger.info("period="+period+"===========doBatch end=============\ntotal cycleCnt="+cycleCnt);
	}
	/*
	 * *该方法是计算激活比例，由于一次判断需要判断省和地市的激活比例是否达标，因此需要调用两次，每次传入的bo不一样
	 */
	private boolean	canDoBatch4AreaLimit(BusiObj bo)throws BaseException
	{
		boolean	flag	=false;
		String	AreaPercent			=	bo.getString("AreaPercent");
		String	allValidCnt			=	bo.getString("allValidCnt");//地区有效旺铺用户数
		String	NotActivationCnt	=	bo.getString("NotActivationCnt");;
		String	ActivationCnt		=	bo.getString("ActivationCnt");
		String	areaLimit			=	bo.getString("areaLimit");

		int	iAllValidCnt			=	Integer.parseInt(allValidCnt);
		int	iActivationCnt			=	Integer.parseInt(ActivationCnt);
		int	iAreaPercent			=	Integer.parseInt(AreaPercent);
		//计算激活比例，小数点取double
		double	dPercent			=	(double)iActivationCnt/(double)iAllValidCnt;
		//换算成整数，小数点后两位都换算，因此乘以10000
		int	iPercent				=	(int)(dPercent*10000.00);
		//减少log
		if(iPercent%100==0)
			vLogger.info("===========AreaPercent="+String.valueOf(AreaPercent)+"===========dPercent="+String.valueOf(dPercent)+
					 "\n=============iPercent="+String.valueOf(iPercent)+"===========iActivationCnt="+String.valueOf(iActivationCnt)+
					 "\n===========iAllValidCnt="+String.valueOf(iAllValidCnt)
					);
		//激活比例小于定义的比例，则返回真，
		if(iPercent<iAreaPercent)
			flag					=	true;
		return	flag;
				
	}
	private BusiObj	updateAreaConfig(BusiObj bo)throws BaseException
	{

		String	NotActivationCnt	=	bo.getString("NotActivationCnt");;
		String	ActivationCnt		=	bo.getString("ActivationCnt");
		int		iActivationCnt				=	0,
				iNotActivationCnt			=	0;
		iActivationCnt				=	Integer.valueOf(ActivationCnt)+1;
		iNotActivationCnt			=	Integer.valueOf(NotActivationCnt)-1;
		bo.setString("NotActivationCnt", String.valueOf(iNotActivationCnt));
		bo.setString("ActivationCnt", String.valueOf(iActivationCnt));
		return	bo;
				
	}
	private HashMap<String ,BusiObj> setupConfig(Connection conn,BusiObj	periodPercentBo)throws BaseException
	{
		
		HashMap<String ,BusiObj>	hConfig
										=	setupAllValidAndAcivationConfig(conn, periodPercentBo);
		HashMap<String ,BusiObj>	hConfig4NotActivation
										=	setupNotAcivationConfig(conn,periodPercentBo);
		int	iSize						=	0;
		int	totalNotActivationCnt		=	0,
			totalActivationCnt			=	0,
			iActivationCnt				=	0,
			iNotActivationCnt			=	0;
		for(String area:hConfig.keySet())
		{
			if(area.trim().equals(PROVINCE_AREA_CODE))
				continue;
			//获取地区配置信息
			BusiObj areaConfigBo 		=	hConfig.get(area);
			String	AreaPercent			=	areaConfigBo.getString("AreaPercent");
			String	allValidCnt			=	areaConfigBo.getString("allValidCnt");//地区有效旺铺用户数
			//获取地区未激活旺铺用户数信息
			BusiObj areaConfigBo4NotActivation 
										=	hConfig4NotActivation.get(area);
			String	NotActivationCnt="0";
			if(areaConfigBo4NotActivation!=null)
				NotActivationCnt		=	areaConfigBo4NotActivation.getString("cnt");
			//计算地区激活旺铺用户数
			String	ActivationCnt		=	String.valueOf( Integer.parseInt(allValidCnt)-Integer.parseInt(NotActivationCnt));
			//String area_code	=	areaConfigBo.getString("area_code");
			//更新地区未激活旺铺用户数、已激活旺铺用户数
			areaConfigBo.setString("NotActivationCnt", NotActivationCnt);
			areaConfigBo.setString("ActivationCnt", ActivationCnt);
			vLogger.info("===========setupConfig(1-"+iSize+") :area_code="+area+";    allValidCnt="+allValidCnt+";    NotActivationCnt="+NotActivationCnt+";    ActivationCnt="+ActivationCnt+";    iAreaPercent=" +AreaPercent);
			//更新地区配置信息
			hConfig.put(area,areaConfigBo);
			iActivationCnt				=	Integer.valueOf(ActivationCnt);
			iNotActivationCnt			=	Integer.valueOf(NotActivationCnt);
			totalNotActivationCnt		=	totalNotActivationCnt+iNotActivationCnt;
			totalActivationCnt			=	totalActivationCnt+iActivationCnt;
			iSize++;

		}
		//设置省的配置数据
		{
			BusiObj provinceConfigBo			=	hConfig.get(PROVINCE_AREA_CODE);
			//provinceConfigBo.setString("AreaPercent", percent);
			//provinceConfigBo.setString("allValidCnt", String.valueOf(totalWPUsers));
			provinceConfigBo.setString("NotActivationCnt", String.valueOf(totalNotActivationCnt));
			provinceConfigBo.setString("ActivationCnt", String.valueOf(totalActivationCnt));
			//provinceConfigBo.setString("areaLimit", String.valueOf(thisPeriodTotalLimit));
			hConfig.put(PROVINCE_AREA_CODE, provinceConfigBo);
		}

		vLogger.info("===========setupConfig(2):hConfig="+hConfig);
		
		return hConfig;
		//0.4	获取未激活的旺铺用户数，也分地区，与前面所有有效用户数查询的区别是主要增加了没有模板的条件
		
	}
	private String	genPeriodCondition(String period)throws BaseException
	{
		String	periodCondition	=	" and to_char(tt1.wp_eff_date,'yyyymm')<='"+period+"' ";
		return	periodCondition;
	}
	private HashMap<String ,BusiObj> setupAllValidAndAcivationConfig(Connection conn,BusiObj	periodPercentBo)throws BaseException
	{
		//	获取批量处理的期间和总体比例
		String	period					=	periodPercentBo.getString("period");
		String	percent					=	periodPercentBo.getString("percent");
		int iPercent					=	Integer.parseInt(percent);
		HashMap<String ,BusiObj>	hConfig	
										=	new HashMap<String ,BusiObj>();
		String sqlCond					=	genPeriodCondition(period);
		//(1)有效旺铺用户数
		//获取所有有效的旺铺用户数，分地区，主要根据订购的旺铺状态=1和企业信息有记录且有效
		String sql 						=	queryCount4AllValidWPInfo(sqlCond);
		SQLArgs 	Arg					= 	new SQLArgs();
		Arg.reset();

		BusiObj		cnt4AllValidWPInfoBo 	
										=	OperAgent.execQuery(conn, "genCount4AllValidWPInfo", sql, Arg,true);
		ArrayList<BusiObj> alAllValidWPInfo
										=	cnt4AllValidWPInfoBo.getBusiObjList(RESULT);
		int iSize						=	0;
		int totalWPUsers				=	0;//所有旺铺用户数，即总用户数
		int thisPeriodTotalLimit		=	0;//本期间总限额=总用户数＊比例
		
		for(BusiObj m:alAllValidWPInfo)
		{
			//areaConfigBo  地区配置，包括地区激活比例、地区用户数、地区未激活用户数、地区限额
			BusiObj	areaConfigBo		=	new BusiObj();
			String area_code			=	m.getString("area_code");
			String	cnt					=	m.getString("cnt");
			int	count					=	Integer.parseInt(cnt);
			
			int iRandom					=	genRandom();
			int	iAreaPercent			=	iPercent+iRandom;
			m.setString("areaPercent", String.valueOf(iAreaPercent));
			vLogger.info("===========setupAllValidAndAcivationConfig(cycle no="+iSize+") :area_code="+area_code+";    allValidCnt="+cnt+"   ;iAreaPercent=" +iAreaPercent);
			int areaLimit				=	genLimit(iAreaPercent, count);
			//地区激活比例
			areaConfigBo.setString("areaPercent",  String.valueOf(iAreaPercent));
			//地区用户数
			areaConfigBo.setString("allValidCnt", cnt);
			//地区未激活用户数
			areaConfigBo.setString("NotActivationCnt", "0");
			//地区限额
			areaConfigBo.setString("areaLimit", String.valueOf(areaLimit));
			hConfig.put(area_code, areaConfigBo);
			totalWPUsers				=	totalWPUsers+count;//累加总用户数
			iSize++;
		}
		//计算本期总限额
		thisPeriodTotalLimit			=	genLimit(iPercent, totalWPUsers);
		//设置省的配置数据
		{
			BusiObj provinceConfigBo			=	new	BusiObj();
			provinceConfigBo.setString("AreaPercent", percent);
			provinceConfigBo.setString("allValidCnt", String.valueOf(totalWPUsers));
			provinceConfigBo.setString("NotActivationCnt", "0");
			provinceConfigBo.setString("ActivationCnt", "0");
			provinceConfigBo.setString("areaLimit", String.valueOf(thisPeriodTotalLimit));
			hConfig.put(PROVINCE_AREA_CODE, provinceConfigBo);
		}
		return	hConfig;
	}
	private HashMap<String ,BusiObj> setupNotAcivationConfig(Connection conn,BusiObj	periodPercentBo)throws BaseException
	{
		String	period					=	periodPercentBo.getString("period");
		String	percent					=	periodPercentBo.getString("percent");

		String sqlCond					=	genPeriodCondition(period);

		String	sql						=	queryCount4NotActivationWPInfo(sqlCond);
		SQLArgs 	Arg					= 	new SQLArgs();
		Arg.reset();
		//vLogger.info("doBatch(2)query genCount4NotActivationWPInfo  sql:" +sql);
		BusiObj		cnt4NotActivationWPInfoBo 	
										=	OperAgent.execQuery(conn, "genCount4NotActivationWPInfo", sql, Arg,true);
		//(2)未激活旺铺用户数
		ArrayList<BusiObj> alCnt4NotActivationWPInfo			
										=	cnt4NotActivationWPInfoBo.getBusiObjList(RESULT);
		HashMap<String ,BusiObj>	hConfig4NotActivation	
										=	new HashMap<String ,BusiObj>();
		for(BusiObj n:alCnt4NotActivationWPInfo)
		{
			String area_code4NotActivation	
										=	n.getString("area_code");
			hConfig4NotActivation.put(area_code4NotActivation, n);
			
		}
		return hConfig4NotActivation;
	}
	private void updateAreaLimit(HashMap<String ,BusiObj>	hConfig	,String area_code)throws BaseException
	{
		BusiObj areaConfigBo 		=	hConfig.get(area_code);
		String	AreaPercent			=	areaConfigBo.getString("AreaPercent");
		String	allValidCnt			=	areaConfigBo.getString("allValidCnt");//地区有效旺铺用户数
		int		iAllValidCnt		=	Integer.parseInt(allValidCnt);
		
		String	NotActivationCnt	=	areaConfigBo.getString("NotActivationCnt");//地区有效旺铺未激活用户数
		int		iNotActivationCnt	=	Integer.parseInt(NotActivationCnt);
		
		int		iActivationCnt		=	iAllValidCnt - iNotActivationCnt;
		String	ActivationCnt		=	String.valueOf(iActivationCnt );
	}
	private void genFixEffExp() throws BaseException
	{
		exp_date_2090					=	__CmPublic.genEffExpDate(2);
		eff_date_now					=	__CmPublic.genEffExpDate(1);

	}
	public BusiObj genWPInfo(BusiObj bo,Order order)throws BaseException
	{
		BusiObj wpInfo					=	new BusiObj();
		//bo.setRawData(aData)
		//this.genPricePlanInst(bo, order);
		this.genSmsTemplete(bo, order);
		this.genTriggerPhone(bo, order);
		this.genSmsTempleGroup(bo, order);
		//this.genSmsTempleRulesReal(bo, order);
		return wpInfo;
	}
	public BusiObj genCustomerGroup(BusiObj bo,Order order)throws BaseException
	{
		//customer_group
		BusiObj	customerGroupBO			=	new	BusiObj();
		customerGroupBO.setConnection(bo.getConnection());
		String	ent_code				=	bo.getString("ent_code");
		String	group_type				=	bo.getString("group_type");
		String	oper_time				=	bo.getString("oper_time");
		String	group_id				=	"";
		customerGroupBO.setString("ent_code",ent_code );
		customerGroupBO.setString("group_type",group_type );
		
		customerGroupBO					=	order.getCustGroupByEntAndType(customerGroupBO);
		ArrayList<BusiObj> group 		= 	customerGroupBO.getBusiObjList(RESULT);
		boolean reGetGroupIdflag		=	false;
		if(group.size()==0)
		{
			customerGroupBO				=	new BusiObj() ;
			group_id					=	"-1";
				//增加企业默认群组
			customerGroupBO.setString("ent_code", ent_code);
			customerGroupBO.setString("group_id", group_id);
			customerGroupBO.setString("GROUP_NAME", "默认群组");
			customerGroupBO.setString("NOTES", "所有拨打企业电话的手机用户");
			customerGroupBO.setString("GROUP_TYPE", group_type);
			//vLogger.info("已有企业新增默认客户群组");
			reGetGroupIdflag 			=	true;
		}
		else if(group.size()>0)
		{
			customerGroupBO				=	group.get(0);	
			group_id					=	customerGroupBO.getString("group_id");
		}
	
		customerGroupBO.setString("state", "1");
		customerGroupBO.setString("oper_time", oper_time);
		customerGroupBO.setString("new_flag", "1");
		if(reGetGroupIdflag)
		{
			customerGroupBO.setConnection(bo.getConnection());
			HashMap<String,String> hTable
										= hSetTableConfig.get(CUSTOMER_GROUP);
			this.setSingleTable(customerGroupBO, hTable);
/*			if(bDebugFlag)
				customerGroupBO			=	debug4getCustGroupByEntAndType(customerGroupBO);
			else
				customerGroupBO			=	order.getCustGroupByEntAndType(customerGroupBO);
			group 						= 	customerGroupBO.getBusiObjList(RESULT);
			customerGroupBO				=	group.get(0);
			group_id					=	customerGroupBO.getString("group_id");*/
		}
		return customerGroupBO;
		
	}
	public BusiObj debug4getCustGroupByEntAndType(BusiObj bo)throws BaseException
	{
		String tableName					=	"customer_group_dbg";
		HashMap<String,String> hCondition	=	new 	HashMap<String,String>();
		String	conditionCol				=	"ENT_CODE";
		String	ENT_CODE					=	bo.getString(conditionCol);
		hCondition.put(conditionCol,ENT_CODE);
		conditionCol						=	"GROUP_TYPE";
		String	group_type					=	bo.getString(conditionCol);
		hCondition.put(conditionCol,group_type);
		return __CmPublic.getSimpleTableDataWithCondition(bo, tableName,hCondition);
	}
	public BusiObj setSingleTable(BusiObj bo,HashMap<String,String> hTable)throws BaseException
	{
		BusiObj retBO					=	new BusiObj();
		String	tableName				=	hTable.get(TABLE_NAME);
		String	listName				=	hTable.get(LIST_NAME);
		if(bDebugFlag)
		{
			String	subfixx				=	"_dbg";
			tableName					=	tableName+subfixx;
			listName					=	listName+subfixx;
		}
		String	staffNo					=	bo.getString("SESSION_STAFF_NO", "");
		BusiObj	serBO					=	new BusiObj();
		serBO.setConnection(bo.getConnection());
		//boCall.setValue(bo_list_name, inBO.getBusiObjList(service_table_name));
		serBO.setValue(listName, bo);
		if(__CmPublic.isStrNullOrEmpty(staffNo))
		{
			staffNo						=	"9999";
			bo.setString("SESSION_STAFF_NO", staffNo);
		}
		HashMap<String,String>hCol		=	null;
		//__CmPublic.setTableData(serBO, listName, tableName,hCol);
		this.setTableData(serBO, listName, tableName,hCol);
		retBO.setValue("ResultFlag", "0");
		return retBO;
	}
	
	public BusiObj genSmsTempleGroup(BusiObj bo,Order order)throws BaseException
	{
		BusiObj	smsTempleGroupBO		=	new BusiObj();
		smsTempleGroupBO.setConnection(bo.getConnection());
		String	sms_temple_id			=	bo.getString("sms_temple_id");
		String	group_id_cust			=	this.genCustomerGroup(bo, order).getString("group_id");
		smsTempleGroupBO.setString("SMS_TEMPLE_ID", sms_temple_id);
		smsTempleGroupBO 				=	order.getSmsTempleGroupBySmsTempleId(smsTempleGroupBO);
		ArrayList<BusiObj> customerGroup
										=	smsTempleGroupBO.getBusiObjList(RESULT);
		if(customerGroup.size()==0)
		{
			smsTempleGroupBO.setString("group_id", group_id_cust);
			smsTempleGroupBO.setString("TEMPLE_GROUP_SN", "-1");
			smsTempleGroupBO.setString("SMS_TEMPLE_ID", sms_temple_id);
			smsTempleGroupBO.setString("GROUP_TYPE", "0");
		}
		else
		{
			smsTempleGroupBO			=	customerGroup.get(0);
		}
		
		smsTempleGroupBO.setConnection(bo.getConnection());
		smsTempleGroupBO.setString("new_flag", "1");
		HashMap<String,String> hTable	=	hSetTableConfig.get(SMS_TEMPLE_GROUP);
		this.setSingleTable(smsTempleGroupBO, hTable);
		return smsTempleGroupBO;
	}
	public String genAreaNoByAreaCode(BusiObj bo,Order order)throws BaseException
	{
		String	areaNo					=	"";
		String	area_code				=	bo.getString("area_code","");
		if (CmPublic.isStrNullOrEmpty(area_code))
			throw new BaseException("batchActivation-0002","获取区号错误，区域编码area_code为空");
		String	sql						=	"select area_no from area where cat_code = :cat_code";
		SQLArgs 	Arg					= 	new SQLArgs();
		Arg.reset();
		Arg.setArg("cat_code", area_code);
		areaNo 							= OperAgent.QueryString(bo.getConnection(), "genAreaNoByAreaCode", sql, Arg);
		return	areaNo;
	}
	public BusiObj genPricePlanInst(BusiObj bo,Order order)throws BaseException
	{
		BusiObj pricePlanInstBO			=	new BusiObj();
		String	order_sn				=	bo.getString("order_sn");
		String	offer_id				=	bo.getString("offer_id");
		String	oper_time				=	bo.getString("oper_time");
		pricePlanInstBO.setString("SUBS_ID",order_sn );
		pricePlanInstBO.setConnection(bo.getConnection());
		pricePlanInstBO					=	order.getPricePlanInstBySubsId(pricePlanInstBO);
		ArrayList<BusiObj> pricePlanInst
										=	pricePlanInstBO.getBusiObjList(RESULT);
		if(pricePlanInst.size()==0)
		{
			pricePlanInstBO				=	new BusiObj() ;
			//order_sn		=	"-1";
			pricePlanInstBO.setString("SUBS_UPP_INST_ID", "-1");
			pricePlanInstBO.setString("SUBS_ID",order_sn);
			pricePlanInstBO.setString("CREATED_DATE", eff_date_now);
			pricePlanInstBO.setString("EFF_DATE", eff_date_now);
			pricePlanInstBO.setString("EXP_DATE", exp_date_2090);
			pricePlanInstBO.setString("STATE", "1");
			pricePlanInstBO.setString("STATE_DATE", eff_date_now);
			pricePlanInstBO.setString("UPDATE_DATE", eff_date_now);
			pricePlanInstBO.setString("OFFER_ID", offer_id);
			pricePlanInstBO.setString("PRICE_PLAN_ID", offer_id);
			pricePlanInstBO.setString("COMPLETED_DATE", eff_date_now);
			pricePlanInstBO.setString("new_flag", "1");
		}
		else if(pricePlanInst.size()>0)
		{
			pricePlanInstBO				=	pricePlanInst.get(0);	
			//ent_code=enterpriseBO.getString("ent_code");
		}
		pricePlanInstBO.setString("STATE", "1");
		pricePlanInstBO.setString("new_flag", "1");
		pricePlanInstBO.setString("OFFER_ID", offer_id);
		pricePlanInstBO.setString("PRICE_PLAN_ID", offer_id);
		pricePlanInstBO.setString("oper_time", oper_time);
		
		pricePlanInstBO.setConnection(bo.getConnection());
		HashMap<String,String> hTable	=	hSetTableConfig.get(PRICE_PLAN_INST);
		this.setSingleTable(pricePlanInstBO, hTable);
		return pricePlanInstBO;
	}
	//mode:1,day;	2,hour;	3,minute;	4,second
	private String	genDateTimeString(int iRandom,int mode)
	{
		String	ret	=	"";
		int	iSize	=	1;
		switch(mode)
		{
			case	1:
				iSize	=	28;
				break;
			case	2:
				iSize	=	24;
				break;
			case	3:
				iSize	=	60;
				break;
			case	4:
				iSize	=	77;
				break;
		
		}
		int	iRet						=	iRandom%iSize	;//+	1
		if(mode==1&&iRet==0)
			iRet=1;
		if(mode==4&&iRet>17)
			iRet	=	iRet	-	18;

			
		ret	=	String.valueOf(iRet);
		if(iRet<10)
			ret	=	"0"+ret;
		
		return ret;
	}
	//在指定期间（年月）后，随机生成日期、时间
	//时间格式：'YYYY-MM-DD HH24:MI:SS'
	private String genRandomDayTime(String period)
	{
		//'YYYY-MM-DD HH24:MI:SS'
		int iRandom						=	genRandom();

		String	month					=	period.substring(4);
		String	year					=	period.substring(0,4);
		String	day						=	genDateTimeString(iRandom, 1);
		String	hour					=	genDateTimeString(iRandom, 2);
		String	minute					=	genDateTimeString(iRandom, 3);
		String	second					=	genDateTimeString(iRandom, 4);
		String	randomDayTime			=	year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second;
		return randomDayTime;
	}
	public BusiObj genSmsTemplete(BusiObj bo,Order order)throws BaseException
	{
		BusiObj 	templeBO			=	new BusiObj();
		BusiObj 	smsTempleteBO		=	new BusiObj();
		templeBO.setConnection(bo.getConnection());
		smsTempleteBO.setConnection(bo.getConnection());
		String	ent_code				=	bo.getString("ent_code");
		String	cust_name				=	bo.getString("cust_name");
		String	area_no					=	bo.getString("area_no");
		String order_num				=	bo.getString("order_num");
		String	order_sn				=	bo.getString("order_sn");
		String	oper_time				=	bo.getString("oper_time");
		String	exp_date				=	bo.getString("exp_date");
		String	rules_ins_id			=	bo.getString("rules_ins_id");
		String	period					=	bo.getString("period");
		//'YYYY-MM-DD HH24:MI:SS'

		String	randomDayTime	=	genRandomDayTime(period);
		
		
		String	sms_temple_id			=	"";
		boolean	retrieveSmsTempleFlag	=	false;
		smsTempleteBO.setString("ent_code", ent_code);
		smsTempleteBO					=	order.getSmsTempleteByEnt(smsTempleteBO);
		ArrayList<BusiObj> smsTemple 	= 	smsTempleteBO.getBusiObjList(RESULT);
		if(smsTemple.size()==0)
		{
			templeBO.setString("cust_name",cust_name);
			templeBO.setString("area_no", area_no);
			templeBO.setString("phone_num", order_num);
			String	sms_temple_context	=	"";
			
			//String	sms_temple_id		=	"-1";
			smsTempleteBO.setString("SMS_TEMPLE_ID", "-1");
			smsTempleteBO.setString("ent_code", ent_code);
			smsTempleteBO.setString("order_sn", order_sn);

			if(bWpBatchFlag)
			{
				smsTempleteBO.setString("STATE", "0");
				smsTempleteBO.setString("EFF_DATE", randomDayTime);//TODO 生效时间要取当月，非数据生成时间
				smsTempleteBO.setString("AUDIT_FLAG", "0");
				smsTempleteBO.setString("AUDIT_TIME", "");
				smsTempleteBO.setString("AUDITER", "9999");
				smsTempleteBO.setString("NOTES", "batchAcivation auto");
				templeBO.setConnection(bo.getConnection());
				sms_temple_context		=	genWpBatchSmsContext(templeBO);//TODO 批量处理旺铺短信模板内容特殊
			}
			else
			{
				smsTempleteBO.setString("STATE", "1");
				smsTempleteBO.setString("EFF_DATE", oper_time);
				smsTempleteBO.setString("AUDIT_FLAG", "1");
				smsTempleteBO.setString("AUDIT_TIME", oper_time);
				smsTempleteBO.setString("AUDITER", "9990");
				smsTempleteBO.setString("NOTES", "new auto accept");
				sms_temple_context		=	order.GenSmsContext(templeBO);
			}

			smsTempleteBO.setString("SMS_TEMPLE_CONTEXT", sms_temple_context);
			smsTempleteBO.setString("cdr_type", "4");//ADD AT 20110618 1，忙；2，未接；3，通话；4，全部。
			//String	exp_date			=	CmPublic.genEffExpDate(2);
			smsTempleteBO.setString("EXP_DATE", exp_date);
			smsTempleteBO.setString("rules_ins_id", rules_ins_id);
			retrieveSmsTempleFlag		=	true;
		}
		else
		{
			smsTempleteBO				=	smsTemple.get(0);	
			smsTempleteBO.setString("ent_code", ent_code);
			smsTempleteBO.setString("order_sn", order_sn);
			smsTempleteBO.setString("EFF_DATE", CmPublic.getSysdate());
			smsTempleteBO.setString("AUDIT_FLAG", "1");
			smsTempleteBO.setString("AUDITER", "999");
			smsTempleteBO.setString("AUDIT_TIME", CmPublic.getSysdate());
			smsTempleteBO.setString("NOTES", "batchAcivation auto");
			smsTempleteBO.setString("STATE", "1");
			sms_temple_id				=	smsTempleteBO.getString("sms_temple_id");
			//20120307  task 15已有短信不修改，因此注释
			//tmplBO.setString("cdr_type", "4");//ADD AT 20110618 1，忙；2，未接；3，通话；4，全部。
		}
		smsTempleteBO.setString("new_flag", "1");
		if(bWpBatchFlag)//add at 20121107
			smsTempleteBO.setString("oper_time", randomDayTime);
		else
			smsTempleteBO.setString("oper_time", oper_time);
		
		////////////////////////////////////////////////////////////////
		//add at 20120325 增加模版类型：1,挂机模板；2，群发模板'
		smsTempleteBO.setString("TEMPLE_TYPE", "1");
		smsTempleteBO.setString("operator", "9999");
		smsTempleteBO.setConnection(bo.getConnection());
		HashMap<String,String> hTable	= hSetTableConfig.get(SMS_TEMPLETE);
		this.setSingleTable(smsTempleteBO, hTable);
		
/*		if(retrieveSmsTempleFlag)
		{
			BusiObj 	smsTempBO		=	new BusiObj();
			smsTempBO.setConnection(bo.getConnection());
			smsTempBO.setString("ent_code", ent_code);
			if(bDebugFlag)
				smsTempBO				=	this.debug4getSmsTempleteDbgByEnt(smsTempBO);
			else
				smsTempBO				=	order.getSmsTempleteByEnt(smsTempBO);
			smsTemple 					=	smsTempBO.getBusiObjList(RESULT);
			smsTempBO					=	smsTemple.get(0);	
			sms_temple_id				=	smsTempBO.getString("sms_temple_id");
		}*/
		sms_temple_id				=	smsTempleteBO.getString("sms_temple_id");
		//先用这种方式设置回sms_templete_id
		bo.setString("sms_temple_id", sms_temple_id);
		return smsTempleteBO;
	}
	public String genWpBatchSmsContext(BusiObj bo)throws BaseException
	{//TODO
		String cust_name 				=	bo.getString("cust_name");
		String area_no 					=	bo.getString("area_no");
		String phone_num 				=	bo.getString("phone_num");
		int iRandom						=	genRandom();
		int	iSize						=	hWpTemple.size();
		int	iIndex						=	iRandom%iSize	+	1;
		String	wpTempleInfo			=	hWpTemple.get(String.valueOf(iIndex));
		String	context					=	wpTempleInfo.replace(varEntName, cust_name);
		context							=	context.replace(varOrderNum, area_no+phone_num);
		return context;
		//return "感谢您的来电与支持，我们将竭诚为您提供更优质的服务，祝您生活愉快！"+"（"+area_no+"-"+phone_num+"）";
	}
	private BusiObj debug4getSmsTempleteDbgByEnt(BusiObj bo)throws BaseException
	{
		String tableName				=	"sms_templete_dbg";
		HashMap<String,String> hCondition	=	new 	HashMap<String,String>();
		String	conditionCol			=	"ENT_CODE";
		String	ENT_CODE				=	bo.getString(conditionCol);
		hCondition.put(conditionCol,ENT_CODE);
		//add at 20120423  取模版信息，只能取拦截模版
		conditionCol					=	"TEMPLE_TYPE";
		String	temple_type				=	"1";
		hCondition.put(conditionCol,temple_type);
		return __CmPublic.getSimpleTableDataWithCondition(bo, tableName,hCondition);
	}
	public String	genSpecialServFlag(BusiObj bo,Order order)throws BaseException
	{
		String	area_no					=	bo.getString("area_no");
		String	order_num				=	bo.getString("order_num");
		String	special_serv_flag		=	"0";
		if(CmPublic.isStrNullOrEmpty(area_no))
		{
			boolean bMobile				=	CmPublic.isMobileNum(order_num);
			if(!bMobile)
				throw new BaseException("信息校验错误","挂机名片（固话业务），区号不能为空");
			else
			{
				area_no					=	order.addMobileAreaNo(order_num,bo.getConnection());
				special_serv_flag		=	"9";
			}
		}
		return special_serv_flag;
	}
	public BusiObj genTriggerPhone(BusiObj bo,Order order)throws BaseException
	{
		BusiObj		triggerPhoneBO		=	new BusiObj() ;
		triggerPhoneBO.setConnection(bo.getConnection());
		String	sms_temple_id			=	bo.getString("sms_temple_id");
		String	order_num				=	bo.getString("order_num");
		String	oper_time				=	bo.getString("oper_time");
		String	area_no_mobile			=	"";
		//String	area_no_mobile	=	bo.getString("area_no_mobile");
		String	area_no					=	bo.getString("area_no");
		triggerPhoneBO.setString("sms_temple_id", sms_temple_id);
		triggerPhoneBO					=	order.getTriggerPhoneBySmsTempleId(triggerPhoneBO);
		ArrayList<BusiObj> triggerPhone = triggerPhoneBO.getBusiObjList(RESULT);
		if(triggerPhone.size()==0)
		{
			triggerPhoneBO.setString("phone_sn", "-1");

		}
		else
		{
			triggerPhoneBO				=	triggerPhone.get(0);
		}
		triggerPhoneBO.setString("new_flag", "1");
		triggerPhoneBO.setString("oper_time", oper_time);
		//add at 20120208 triggerphone增加特服号码标志
		String	special_serv_flag		=	genSpecialServFlag(bo, order);
		triggerPhoneBO.setString("special_serv_flag", special_serv_flag);//add at 20120831
		//add at 20120215 triggerphone增加付费号码标志
		//triggerPhoneBO.setString("true_VOUCH_NUMBER", area_no+order_num);
		{
			triggerPhoneBO.setString("sms_temple_id", sms_temple_id);
			//triggerPhone.setString("mobile_num", "3659663");
			triggerPhoneBO.setString("phone_num", order_num);
			/////////////////////add at 20120831 手机名片不加区号,true_VOUCH_NUMBER不加区号
			boolean bMobile				=	CmPublic.isMobileNum(order_num);
			if(bMobile)
			{
				triggerPhoneBO.setString("area_no", area_no_mobile);
				triggerPhoneBO.setString("true_VOUCH_NUMBER", order_num);
			}				
			else
			/////////////////////add at 20120831 手机名片不加区号 end
			{
				triggerPhoneBO.setString("area_no", area_no);
				triggerPhoneBO.setString("true_VOUCH_NUMBER", area_no+order_num);
			}
			triggerPhoneBO.setString("OPERATOR", "9999");
			triggerPhoneBO.setString("state", "1");
			triggerPhoneBO.setString("oper_time",  oper_time);
			triggerPhoneBO.setString("new_flag", "1");
		}
		
		triggerPhoneBO.setConnection(bo.getConnection());
		HashMap<String,String> hTable	=	hSetTableConfig.get(TRIGGER_PHONE);
		this.setSingleTable(triggerPhoneBO, hTable);
		return triggerPhoneBO;
	}
	public String genRulesInsId(BusiObj bo,Order order)throws BaseException
	{
		BusiObj		StaticBO			=	new BusiObj() ;
		StaticBO.setConnection(bo.getConnection());
		StaticBO.setString(TABLE_NAME, "rules_ins_id");
		String rules_ins_id 			=	order.getOneStaticValue(StaticBO);
		return rules_ins_id;
	}
	public BusiObj genSmsTempleRulesReal(BusiObj bo,Order order)throws BaseException
	{
		BusiObj smsTempleRulesRealBo 	= 	new BusiObj();
		String	sms_temple_id			=	bo.getString("sms_temple_id");
		smsTempleRulesRealBo.setConnection(bo.getConnection());
		//rules也需要跟其余的业务信息一样的操作
		smsTempleRulesRealBo.setString("sms_temple_id", sms_temple_id);
		
		//String rules_ins_id 			=	genRulesInsId(bo, order);
		String rules_ins_id 			=	bo.getString("rules_ins_id");
		
		smsTempleRulesRealBo			=	order.getRulesBySmsTempleId(smsTempleRulesRealBo);
		ArrayList<BusiObj> rules 		= 	smsTempleRulesRealBo.getBusiObjList(RESULT);
		
		if(rules.size()==0)
		{
			//triggerPhoneBO.setString("phone_sn", "-1");
			/////////////////////////////////////////////////add at 20110626
			{
				smsTempleRulesRealBo.setString("rules_ins_id", rules_ins_id);
				smsTempleRulesRealBo.setString("sms_temple_id", sms_temple_id);

			}

		}
		else
		{
			smsTempleRulesRealBo		=	rules.get(0);
		}
		smsTempleRulesRealBo.setString("oper_id", "999");
		smsTempleRulesRealBo.setString("state", "1");
		smsTempleRulesRealBo.setString("new_flag", "1");
		smsTempleRulesRealBo.setString("oper_date", CmPublic.getSysdate());
		
		smsTempleRulesRealBo.setConnection(bo.getConnection());
		HashMap<String,String> hTable	=	hSetTableConfig.get(SMS_TEMPLE_RULES_REAL);
		this.setSingleTable(smsTempleRulesRealBo, hTable);
		return smsTempleRulesRealBo;
	}
	public String logBatchBiz(BusiObj bo)throws BaseException
	{
		String logSn					=	"";
		Connection	conn				=	bo.getConnection();
		String	tableName				=	"";
		SQLArgs 	Arg					= 	new SQLArgs();
		{
			tableName="log_batch_BizSF";
			Arg.reset();

			String 	area_code			=	bo.getString("area_code","");
			String 	area_no				=	bo.getString("area_no","");
			String 	vouch_number		=	bo.getString("vouch_number","");
			String 	ent_code			=	bo.getString("ent_code","");
			String	wp_order_time		=	bo.getString("wp_order_time","");
			String	wp_biz_type			=	bo.getString("wp_biz_type","");
			String	wp_state			=	bo.getString("wp_state","");
			String	wp_oper_time		=	bo.getString("wp_oper_time","");
			String 	wp_eff_date 		= 	bo.getString("wp_eff_date","");
			String	order_sn			=	bo.getString("order_sn","");
			String	cust_name			=	bo.getString("cust_name","");
			String	order_num			=	bo.getString("order_num","");
			String 	wp_batch_flag 		= 	bo.getString("wp_batch_flag","");
			String	offer_id			=	bo.getString("offer_id","");
			String	group_type			=	bo.getString("group_type","");
			String	rules_ins_id		=	bo.getString("rules_ins_id","");
			String	original_offer_id	=	bo.getString("original_offer_id","");
			
			String	log_time						=	CmPublic.getSysdate();;
			String	log_batch_bizsf_sn				=	__CmPublic.genSequencePK("LOG_BATCH_BIZSF_SN", conn);
			bo.setString("log_time", log_time);
			bo.setString("LOG_BATCH_BIZSF_SN", log_batch_bizsf_sn);
			this.insertOneRow(bo, tableName.toUpperCase(), conn);
/*			
			HashMap<String,String> hColDataType		=	new	HashMap<String,String> ();
			hColDataType.put("wp_order_time", "DATE");
			hColDataType.put("wp_oper_time", "date");
			hColDataType.put("wp_eff_date", "date");
			hColDataType.put("LOG_TIME", "date");
			HashMap<String,String> hColValue		=	new	HashMap<String,String> ();
			
			hColValue.put("area_code", area_code);
			hColValue.put("area_no", area_no);
			hColValue.put("vouch_number", vouch_number);
			hColValue.put("ent_code", ent_code);
			hColValue.put("wp_order_time", wp_order_time);
			hColValue.put("wp_biz_type", wp_biz_type);
			hColValue.put("wp_state", wp_state);
			hColValue.put("wp_oper_time", wp_oper_time);
			hColValue.put("wp_eff_date", wp_eff_date);
			hColValue.put("order_sn", order_sn);
			hColValue.put("cust_name", cust_name);
			
			hColValue.put("order_num", order_num);
			hColValue.put("wp_batch_flag", wp_batch_flag);
			hColValue.put("offer_id", offer_id);
			hColValue.put("group_type", group_type);
			hColValue.put("rules_ins_id", rules_ins_id);
			hColValue.put("original_offer_id", original_offer_id);
			
			hColValue.put("log_time", log_time);
			hColValue.put("LOG_BATCH_BIZSF_SN", log_batch_bizsf_sn);
			//add at 20120418 订购接口增加sys_src字段

			
			__CmPublic.execInsertSqlByHash(conn, tableName, hColDataType, hColValue);*/
			logSn						=	log_batch_bizsf_sn;
			

		}
		return logSn;
	}
	private void dbExcuteBatch(Connection conn)throws BaseException
	{
		try {
			   for(String tableName:hSetTableConfig.keySet())
			   {
				   tableName			=	this.genTableName4DebugMode(tableName);
/*				   if(tableName.indexOf("SMS_TEMPLETE")>=0)
					   continue;*/
				   PreparedStatement	tablePst	=	hPst.get(tableName);
				   tablePst.executeBatch();
			   }
			
		} catch (SQLException e) {
			// TODO Auto-generated catch bloc
			vLogger.debug(LogCollect.getStackLog(e));//add at 20120524k
			e.printStackTrace();
			throw new BaseException("数据批量更新失败",e.getMessage());
		}
	}
	private void dbCommit(Connection conn)throws BaseException
	{
		try {
			conn.commit();
		} catch (SQLException e) {
			// TODO Auto-generated catch bloc
			vLogger.debug(LogCollect.getStackLog(e));//add at 20120524k
			e.printStackTrace();
			throw new BaseException("数据提交失败",e.getMessage());
		}
	}
	private void genPK(BusiObj curRecordBO,ArrayList<String>	aTableKey,Connection conn) throws BaseException
	{
	       String 	 	curKeyValue		=	"";  
	       String 		seq				=	""; 
		   for(String curKey:aTableKey)
		   {
			   curKeyValue				=	curRecordBO.getString(curKey);
			   if(Integer.parseInt(curKeyValue)<=0)
			   {
				   //get sequence
				   seq 					= 	__CmPublic.genSequencePK(curKey, conn);
				   curRecordBO.setString(curKey, seq);
			   }
		   }
	}	
	/**插入一行数据
	 * */
	private void insertOneRow(BusiObj bo,String tableName,Connection conn ) throws BaseException
	{
		String 	tableCols				=	" ",tableColsVar="";
		String	columnDataType			=	"";
		String 	sql						=	" ";
		//sql					=	" Insert Into  "+tab_name+" ($columns) Values ($columns) ";
	   
	   HashMap<String,Object> hRowData	=	bo.getRawData();
	   try
	   {
		   String colValue				=	"";
/*		   String	pkTable				=	this.getPKTableName(tableName);
		   HashMap<String, String>	hTableColsInfo	=	hTablesColumnsInfo.get(pkTable);*/
		   int	i						=	1;
		   ArrayList<String>	aCols	=	new	ArrayList<String>();
/*		   for(String colName:hTableColsInfo.keySet())
		   {
			   tableCols				=	tableCols+colName+", ";
			   colValue					=	(String)hRowData.get(colName);
			   columnDataType			=	hTableColsInfo.get(colName);
			   if(columnDataType.equals("DATE") && !CmPublic.isStrNullOrEmpty(colValue) )
				   tableColsVar			=	tableColsVar+"TO_DATE("+"?,'YYYY-MM-DD HH24:MI:SS')"+", ";
			   else
				   tableColsVar			=	tableColsVar+"?, ";
			   //Arg.setArg(colName, colValue);
			   aCols.add(colValue);
			   
			   i++;
		   }
	
		   tableCols					=	this.processCols(tableCols);
		   tableColsVar					=	this.processCols(tableColsVar);
		   sql							=	" Insert Into  "+tableName+" ( "+tableCols+") Values ("+tableColsVar+") ";
		   pst							=	conn.prepareStatement(sql); */
		   i							=	1;
		   PreparedStatement	tablePst	=	hPst.get(tableName);
		   aCols						=	hPstTablesCols.get(tableName);
		   for(String	value:aCols)
		   {
			   colValue					=	(String)hRowData.get(value);
			   tablePst.setString(i, colValue);
			   i++;
		   }
		   tablePst.addBatch();
		   //http://lavasoft.blog.51cto.com/62575/238651
		   //http://xuliangyong.iteye.com/blog/237728
		}
		catch(SQLException e)
		{
			throw new BaseException(vName +"-019","插入表名为："+tableName+"的数据出错：\n sql="+sql+"\n"+e.getMessage());
		}
		finally
		{
	    	try
	    	{		    		
	    		//rs.close();

	    	}
	    	catch(Exception e){}
		}   

    	//vLogger.info("=====================insert row "+tableName+"    sql:" + sql);
    	//OperAgent.execUpdate(conn, "insert  "+tableName,sql, vArg);
	}
	/*删除字段列表等后面多余的","
	 * */
	private String processCols(String cols)
	{
		String ret_value				=	"";
		int	beginIndex					=	0;	
		String	str						=	cols.trim();
		ret_value						=	str.substring(beginIndex, str.length()-1);
		return ret_value;
	}
	private String getPKTableName(String tableName)
	{
		int	length						=	tableName.length();
		String	pkTable					=	"";
		if(tableName.substring(length-4).equals("_DBG"))
			pkTable						=	tableName.substring(0,length-4);
		else
			pkTable						=	tableName;
		return	pkTable;
	}
	
	/**新增、删除、修改（先删后插）单表数据，必须是有主键的表
	 * 入参：
	 * 						bo：		记录bo，
	 *  			listName：	记录集名称
	 *  			tabName：	表名
	 *  HashMap<String,String>hCol	：		需要替换值的字段名+字段值（前台无法确定的值，比如staff字段等）
	 * */
	public void setTableData(BusiObj bo,String listName,String tabName,HashMap<String,String>hCol ) throws BaseException
	{
		ArrayList<BusiObj> member 		= bo.getBusiObjList(listName);
		Connection	conn				=	bo.getConnection();
		String 	newFlag 				= "";//bo.getString("new_flag"); //0:不重新插入记录。//1：重新插入记录
		String	tableName				=	tabName.trim().toUpperCase();//统一转化为大写
		String	pkTable					=	this.getPKTableName(tableName);
		ArrayList<String>	aTableKey	=	hTablesPK.get(pkTable.toUpperCase());//得到主键
		if(aTableKey.size()<1)
			throw new BaseException(vName +"-008","表名为："+tableName+"没有定义主键，不能使用方法setTableData进行数据处理！");
		boolean flagReplaceRow=false;
		if(hCol !=null) flagReplaceRow=true;
		for (BusiObj m : member) 
		{
			
			newFlag 					= m.getString("new_flag","");
			
			{
				//if(flagReplaceRow)	CmPublic.replaceRowColumn(m, hCol);
				this.genPK(m, aTableKey, conn);//生成主键，如果为负数
				this.insertOneRow(m, tableName,conn);//,aTableKey
			}
		}
	}
	
	
	public static void main(String[] args)  {
		Connection conn	=null;
		try{
			//ETLLoger.getInstance().printInfo("---------------InitSystem-------------");
			int i=0;
			System.out.println("vName"+vName);
			vLogger = Logger.getLogger(BatchActivation.class);
			vLogger.debug(vName);
			vLogger.info("---------------InitSystem-------------");
			Configuration.InitSystem();
			conn = DBTrans.getConnection();
			BatchActivation	batchActivation= new BatchActivation(conn,true);
			batchActivation.setDebugFlag();
			//batchActivation.setDebugRowsLimit();
			vLogger.info("---------------BatchActivation-------------");
			//batchActivation.doActivationAuto(conn);
			vLogger.info("---------------doActivationManual-------------");
			String period ="";
			period = args[0];
			if (period=="") 
				period ="201305";
			batchActivation.doActivationManual(conn,period);
			conn.commit();//remember to remark
			//conn.rollback();
			conn.close();

		}

		catch(Exception e)
		{
			try {
				conn.rollback();
				conn.close();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
			vLogger.error(e.getCause());
			e.printStackTrace();
		}
		finally
		{
		/*	try{
				if(pst != null) pst.close();
				if(rs != null) rs.close();
			}*/
		}
			vLogger.info("---------------Game Over-------------");
	

		
	}
	

}
